import json
import os
import uuid
import datetime
import traceback
import pandas as pd
from django.contrib import messages
from django.conf import settings
from django.http import HttpResponse, FileResponse, JsonResponse
from django.shortcuts import render, redirect, get_object_or_404
import logging

from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.db.models import Q

from . import do_autogenerate_report
from .forms import ProductBaseInfoForm, ProductAutoReportForm, ProductUploadFileForm
from .models import ProductBaseInfo, ProductDownloadFile
from .mylogin_utils import my_login_admin_required

logger = logging.getLogger(__name__)


def product_batch_info_list(request):
    h_lot_number_query = request.GET.get('h_lot_number')
    production_lot_number_query = request.GET.get('production_lot_number')

    results = ProductBaseInfo.objects.all()

    if h_lot_number_query:
        results = results.filter(h_lot_number__icontains=str(h_lot_number_query).strip())
    if production_lot_number_query:
        results = results.filter(production_lot_number__icontains=str(production_lot_number_query).strip())

    results = results.order_by('-id')  # 按照id降序排列
    
    context = {
        'product_base_info_list': results
    }
    if h_lot_number_query:
        context['h_lot_number'] = h_lot_number_query
    if production_lot_number_query:
        context['production_lot_number'] = production_lot_number_query
    return render(request, 'mainapp/product_batch_info_list.html', context)


@my_login_admin_required
def add_product_base_info(request):
    if request.method == 'POST':
        form = ProductBaseInfoForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('product_batch_info_list')  # 替换为你想要跳转的页面
    else:
        form = ProductBaseInfoForm()
    return render(request, 'mainapp/add_product_base_info.html', {'form': form})


@my_login_admin_required
def delete_product_base_info(request, id):
    product = get_object_or_404(ProductBaseInfo, id=id)
    if request.method == 'POST':
        # 删除下载文件
        ProductDownloadFile.objects.filter(product_base_info=product).delete()
        product.delete()
        return redirect('product_batch_info_list')
    return render(request, 'mainapp/product_base_confirm_delete.html', {'product': product})


@my_login_admin_required
def edit_product_base_info(request, id):
    logger.info("Request method: %s", request.method)
    product = get_object_or_404(ProductBaseInfo, id=id)
    if request.method == 'POST':
        form = ProductBaseInfoForm(request.POST, instance=product)
        if form.is_valid():
            form.save()
            return redirect('product_batch_info_list')
    else:
        form = ProductBaseInfoForm(instance=product)
    return render(request, 'mainapp/edit_product_base_info.html', {'form': form})


def get_files_from_directory(h_lot_number):
    server_dir = str(settings.BASE_DIR / f"datas/server")
    # 尺寸，以及文件名中的标记
    size_files, size_tag = [], "_103_"
    # 直角度，以及文件名中的标记
    angle_files, angle_tag = [], "_102_"
    # 频率，以及文件名中的标记
    frequency_files, frequency_tag = [], "_101_"
    # delat F，以及文件名中的标记
    df_files, df_tag = [], "_101_"

    for root, dirs, files in os.walk(server_dir):
        for file in files:
            if file.startswith(h_lot_number + "_"):
                if size_tag in file:
                    size_files.append(str(os.path.join(root, file)).replace(server_dir, ""))
                if angle_tag in file:
                    angle_files.append(str(os.path.join(root, file)).replace(server_dir, ""))
                if frequency_tag in file:
                    frequency_files.append(str(os.path.join(root, file)).replace(server_dir, ""))
                if df_tag in file:
                    df_files.append(str(os.path.join(root, file)).replace(server_dir, ""))
    size_files.sort(key=get_path_freq_values)
    angle_files.sort(key=get_path_freq_values)
    frequency_files.sort(key=get_path_freq_values)
    df_files.sort(key=get_path_freq_values)
    return server_dir, size_files, angle_files, frequency_files, df_files


def get_path_freq_values(filepath):
    """获取文件路径中的频率段的两个数字值，用于排序
     \MT-01\240509070_TE02712006111_101_频率及△F测试_MT-01_28150-28155_Ethan_2024-05-28-09-08-07.xls
    """
    try:
        filename = os.path.basename(filepath)
        freqs = filename.split("_")[5]
        first, second = freqs.split("-")
        return int(first), int(second)
    except:
        return (0, 0)


def do_auto_generate_report(request, id):
    logger.info("Request method: %s", request.method)
    error_msg = None
    product = get_object_or_404(ProductBaseInfo, id=id)
    server_dir, size_files, angle_files, frequency_files, df_files = get_files_from_directory(product.h_lot_number)
    if request.method == 'POST':
        random_string = uuid.uuid4().hex
        form = ProductAutoReportForm(request.POST, instance=product,
                                     size_files=size_files,
                                     angle_files=angle_files,
                                     frequency_files=frequency_files,
                                     df_files=df_files)
        print("data:", json.dumps(dict(request.POST), indent=4))
        if form.is_valid():
            h_lot_number = form.cleaned_data['h_lot_number']
            h_product_type = form.cleaned_data['h_product_type']
            report_number = form.cleaned_data['report_number']
            report_date = form.cleaned_data['report_date']
            customer_name = form.cleaned_data['customer_name']
            order_number = form.cleaned_data['order_number']
            production_lot_number = form.cleaned_data['production_lot_number']
            specification_model = form.cleaned_data['specification_model']
            lot_quantity = form.cleaned_data['lot_quantity']
            direction_angle = form.cleaned_data['direction_angle']
            feeding_angle = form.cleaned_data['feeding_angle']
            frequency_range = form.cleaned_data['frequency_range']
            frequency_measurement_gap = form.cleaned_data['frequency_measurement_gap']
            customer_material_number = form.cleaned_data['customer_material_number']
            product_size = form.cleaned_data['product_size']
            appearance_sample_quantity = form.cleaned_data['appearance_sample_quantity']
            ma_accept = form.cleaned_data['ma_accept']
            ma_reject = form.cleaned_data['ma_reject']
            frequency_diff_limit = form.cleaned_data['frequency_diff_limit']
            frequency_diff_control = form.cleaned_data['frequency_diff_control']
            frequency_offset_degree = form.cleaned_data['frequency_offset_degree']
            size_data_address = [server_dir + x for x in form.cleaned_data['size_data_address']]
            angle_data_address = [server_dir + x for x in form.cleaned_data['angle_data_address']]
            frequency_data_address = [server_dir + x for x in form.cleaned_data['frequency_data_address']]
            df_data_address = [server_dir + x for x in form.cleaned_data['df_data_address']]
            # 生成下载文件地址
            now = datetime.datetime.now()  # 系统时间提取，格式为2024-04-19 14:09:13.723344
            nowtime = str(now.year) + "-" + str(now.month) + "-" + str(now.day) + "-" \
                      + str(now.hour) + "-" + str(now.minute) + "-" + str(now.second)
            output_excel_filename = f"{production_lot_number}_{h_lot_number}_晶片OQC出货报告_{nowtime}.xlsx"
            output_excel_path = f"{settings.MEDIA_ROOT}/{output_excel_filename}"
            try:
                do_autogenerate_report.do_autogenerate_report(
                    h_lot_number, h_product_type, report_number, report_date,
                    customer_name, order_number, production_lot_number, specification_model,
                    lot_quantity, direction_angle, feeding_angle, frequency_range,
                    frequency_measurement_gap, customer_material_number, product_size, appearance_sample_quantity,
                    ma_accept, ma_reject, frequency_diff_limit, frequency_diff_control, frequency_offset_degree, size_data_address,
                    angle_data_address, frequency_data_address, df_data_address, output_excel_path
                )
                # 保存下载文件信息到数据库
                ProductDownloadFile.objects.create(
                    product_base_info=product,
                    file_path=output_excel_filename
                )
                return redirect('do_auto_generate_report', id=product.id)
            except Exception as e:
                error = traceback.format_exc()
                logger.info("error:", error)
                error_msg = error.replace(" ", "&nbsp;").replace("\n", "<br />")
    else:
        random_string = uuid.uuid4().hex
        form = ProductAutoReportForm(instance=product,
                                     size_files=size_files,
                                     angle_files=angle_files,
                                     frequency_files=frequency_files,
                                     df_files=df_files)
    download_files = ProductDownloadFile.objects.filter(product_base_info=product).order_by("-created_at")
    return render(request, 'mainapp/do_auto_generate_report.html',
                  {'form': form, 'product': product, 'random_string': random_string,
                   'download_files': download_files, 'MEDIA_URL': settings.MEDIA_URL,
                   "error_msg": error_msg})


@csrf_exempt  # 如果遇到 CSRF 验证问题，可以暂时使用 csrf_exempt 装饰器
@require_POST
def delete_download_file(request):
    try:
        data = json.loads(request.body)
        file_id = data.get('file_id')
        if file_id is None:
            return JsonResponse({'status': 'error', 'message': 'File ID not provided'})

        download_file = ProductDownloadFile.objects.get(id=file_id)
        file_path = os.path.join(settings.MEDIA_ROOT, download_file.file_path)

        # 删除文件
        if os.path.exists(file_path):
            os.remove(file_path)

        # 删除数据库记录
        download_file.delete()

        return JsonResponse({'status': 'success'})
    except ProductDownloadFile.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'File not found'})
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)})


@my_login_admin_required
def upload_file(request):
    if request.method == 'POST':
        form = ProductUploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file = request.FILES['file']
            try:
                df = pd.read_excel(file, engine='openpyxl', parse_dates=False)
                excel_epoch = datetime.datetime(1899, 12, 30)  # Excel日期序列号的起始日期
                df['报告日期'] = df['报告日期'].apply(
                    lambda x: (excel_epoch + datetime.timedelta(days=x)).strftime('%Y年%m月%d日'))

                skipped_records = 0
                success_records = 0
                for _, row in df.iterrows():
                    h_lot_number = row['生产批次号']
                    production_lot_number = row['出货批次号']

                    # 判断记录是否存在
                    if ProductBaseInfo.objects.filter(h_lot_number=h_lot_number,
                                                      production_lot_number=production_lot_number).exists():
                        skipped_records += 1
                        continue

                    ProductBaseInfo.objects.create(
                        h_lot_number=row['生产批次号'],
                        h_product_type=row['产品类型'],
                        report_number=row['报告编号'],
                        report_date=row['报告日期'],
                        customer_name=row['客户名称'],
                        order_number=row['订单号码'],
                        production_lot_number=row['出货批次号'],
                        specification_model=row['规格型号'],
                        lot_quantity=row['批量'],
                        direction_angle=row['方向角度'],
                        feeding_angle=row['投料角度'],
                        frequency_range=row['频率范围'],
                        frequency_measurement_gap=row['频率测量间隙'],
                        customer_material_number=row['出货产品料号'],
                        product_size=row['产品尺寸'],
                        appearance_sample_quantity=row['外观抽样数'],
                        ma_accept=row['Ma-ACC'],
                        ma_reject=row['Ma-REJ'],
                        frequency_diff_limit=row['△F规格值'],
                        frequency_diff_control=row['△F管控值'],
                        frequency_offset_degree=row['频率偏移度'],
                    )
                    success_records += 1

                success_message = '文件上传并导入数据成功。'
                if skipped_records:
                    success_message += f' 成功导入{success_records}条记录，略过了 {skipped_records} 条已存在的记录。'
                messages.success(request, success_message)
                return redirect('product_batch_info_list')
            except Exception as e:
                messages.error(request, f'文件处理出错: {e}')
    else:
        form = ProductUploadFileForm()
    return render(request, 'mainapp/product_upload.html', {'form': form})
